package com.ydj.manager;

import org.hibernate.annotations.common.util.impl.LoggerFactory;
import org.jboss.logging.Logger;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;


/**
 * Created by rick on 2015/10/19.
 * 线程管理类，所有线程资源的申请都应该在这里
 */
public class ThreadPoolManager {
    /** 是否打印线程情况 */
    static final boolean OPTIMIZE_DEBUG = false;

    private static Logger logger = LoggerFactory.logger(ThreadPoolManager.class);

    // 线程池的分类
    public enum PoolType {
        /** 线程池的类别 */
        异步统计(1);

        int maxThreadCount;

        PoolType(int maxThreadCount) {
            this.maxThreadCount = maxThreadCount;
        }

        int getMaxThreadCount() {
            return maxThreadCount;
        }
    }

    private volatile static ThreadPoolManager instance = new ThreadPoolManager();

    /** 不同线程池的容器 */
    private List<ThreadPoolExecutorWarp> poolArray;
    private ExecutorService debugThreadPool = null;

    public static ThreadPoolManager getInstance() {
        return instance;
    }

    private ThreadPoolManager() {
        poolArray = new ArrayList<>(PoolType.values().length);
        for (PoolType poolType : PoolType.values()) {
            // 等价于 Executors.newCachedThreadPool();
            ThreadPoolExecutorWarp pool = new ThreadPoolExecutorWarp(0, poolType.getMaxThreadCount(), 60L, TimeUnit.SECONDS, new PriorityBlockingQueue<>());
            poolArray.add(pool);
        }

        // 调优时候查看线程
        if (OPTIMIZE_DEBUG) {
            debugThreadPool = Executors.newSingleThreadExecutor();
            final Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    for (ThreadPoolExecutorWarp pool : poolArray) {
                        pool.printInfo();
                    }
                    sleep(1000);
                    debugThreadPool.execute(this);
                }
            };
            debugThreadPool.execute(runnable);
        }
    }

    /**
     * 任务
     */
    synchronized static void postTask(ThreadPoolTask task, PoolType poolType) {
        ThreadPoolExecutor pool = getInstance().poolArray.get(poolType.ordinal());
        if (!pool.isShutdown()) {
            pool.execute(task);
        }
    }

    /**
     * 关闭所有线程池
     */
    public static synchronized void exit() {
        List<ThreadPoolExecutorWarp> poolArray = getInstance().poolArray;
        for (ThreadPoolExecutor pool : poolArray) {
            if (!pool.isShutdown()) {
                pool.shutdownNow();
            }
        }
        getInstance().poolArray = null;
    }

    /**
     * 用于打印线程池数组现在的情况
     */
    public static void printPoolInfo() {
        StringBuilder sb = new StringBuilder();
        sb.append("自定义的线程池情况：");

        List<ThreadPoolExecutorWarp> poolArray = getInstance().poolArray;
        for (int i = 0; i < poolArray.size(); i++) {
            ThreadPoolExecutorWarp pool = poolArray.get(i);
            sb.append(PoolType.values()[i].name())
                    .append(" 现在使用=").append(pool.getActiveCount())
                    .append(" 最大=").append(pool.getLargestPoolSize())
                    .append(" 总共=").append(pool.getQueue().size())
                    .append(", ");
        }
        logger.info(sb.toString());
    }

    private static void sleep(long ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
